package com.iwhalecloud.bss.kite.cucc.order.accept.chain.impl;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.cucc.order.accept.chain.AbstractOrderHandler;
import com.iwhalecloud.bss.kite.cucc.order.accept.constructor.DataConstructorFactory;
import com.iwhalecloud.bss.kite.cucc.order.accept.constructor.inst.ProdInstAcctRelConstructor;
import com.iwhalecloud.bss.kite.cucc.order.util.AcceptUtils;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.ProdInst;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.ProdInstAcctRel;
import com.iwhalecloud.bss.kite.dataservice.util.IdUtils;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInstAcct;
import com.iwhalecloud.bss.kite.manager.util.ManagerUtils;
import com.iwhalecloud.bss.kite.order.client.dto.InstContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.common.util.SpringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * 订单受理流程：补充账户定制关系
 */
@Component
public class ProdInstAcctRelHandler extends AbstractOrderHandler {

    @Override
    public void doHandle(OrderRequest orderRequest) {
        buildProdInstAcctRels(orderRequest);
    }

    /**
     * 获取场景实例公共属性中的账户信息设置到每一个新增的接入产品实例<br>
     * 多场景实例的情况，判断接入产品实例是在哪个场景实例新增的
     * @param orderRequest
     */
    private void buildProdInstAcctRels(OrderRequest orderRequest) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        List<ProdInst> prodInsts = InstContainer.ofRequest(orderRequest).listProdInsts();
        for (ProdInst prodInst : prodInsts) {
            if (!AcceptUtils.isAddInst(prodInst)
                || hasValidProdInstAcctRel(orderRequest, prodInst.getProdInstId(), prodInst.getOwnerCustId())) {
                continue;
            }

            List<String> sceneInstIds = orderRequest.getSceneInstIds();
            String sceneInstId = getAddInstSceneInstId(sceneInstIds, InstType.PROD_INST, prodInst.getProdInstId());
            KiteAttr attr = querySceneInstService.getCommonAttr(sceneInstId, KeyConsts.ACCT_ID);
            if (Objects.isNull(attr)) {
                continue;
            }

            KiteProdInstAcct prodInstAcct = new KiteProdInstAcct();
            prodInstAcct.setProdInstAcctRelId(IdUtils.generateProdInstAcctRelId());
            prodInstAcct.setInstType(InstType.PROD_INST_ACCT);
            prodInstAcct.setActionType(ActionType.A);
            prodInstAcct.setAcctId(attr.getValue());
            prodInstAcct.setAcctDesc(attr.getValueDesc());
            prodInstAcct.setProdInstId(prodInst.getProdInstId());
            prodInstAcct.setCompInstId(prodInst.getCompInstId());
            prodInstAcct.setAcctItemGroupId(KeyConsts.ACCT_ITEM_TYPE_GROUP_ID);
            prodInstAcct.setIfDefaultAcctId(KeyConsts.IF_DEFAULT_ACCT_ID_TRUE);

            ProdInstAcctRelConstructor dataConstructor = DataConstructorFactory
                .getInstConstructor(InstType.PROD_INST_ACCT);
            ProdInstAcctRel prodInstAcctRel = dataConstructor.convert(orderRequest, prodInstAcct, null);
            InstContainer.ofRequest(orderRequest).addProdInstAcctRel(prodInstAcctRel);

            // 补充实例新增的变动信息
            AcceptUtils.addInstChange(orderRequest, prodInst.getProdInstId(), InstType.PROD_INST,
                prodInstAcct.getProdInstAcctRelId(), prodInstAcct.getInstType(), ActionType.A, "", "", "");
        }
    }

    /**
     * 判断接入产品是否有效的账户定制关系
     * @param orderRequest
     * @param prodInstId
     * @param custId
     * @return
     */
    private boolean hasValidProdInstAcctRel(OrderRequest orderRequest, String prodInstId, String custId) {
        if (Objects.isNull(orderRequest) || StringUtils.isBlank(prodInstId)) {
            return false;
        }

        List<ProdInstAcctRel> prodInstAcctRels = InstContainer.ofRequest(orderRequest).listProdInstAcctRels(prodInstId);
        for (ProdInstAcctRel prodInstAcctRel : prodInstAcctRels) {
            if (StringUtils.equalsAny(prodInstAcctRel.getActionType(), ActionType.A.name(), ActionType.K.name(),
                ActionType.M.name())) {
                return true;
            }
        }

        if (CollectionUtils.isEmpty(prodInstAcctRels)) {
            // 通过缓存判断
            return hasValidProdInstAcctRel(prodInstId, custId);
        }

        return false;
    }

    /**
     * 判断接入产品是否有效的账户定制关系(缓存)
     * @param prodInstId
     * @param custId
     * @return
     */
    private boolean hasValidProdInstAcctRel(String prodInstId, String custId) {
        if (StringUtils.isAnyBlank(prodInstId, custId)) {
            return false;
        }

        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        List<KiteProdInstAcct> prodInstAccts = querySceneInstService.listProdInstAccts(custId, prodInstId);
        for (KiteProdInstAcct prodInstAcct : prodInstAccts) {
            String actionType = ManagerUtils.getEnumName(prodInstAcct.getActionType());
            if (StringUtils.equalsAny(actionType, ActionType.A.name(), ActionType.K.name(), ActionType.M.name())) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取新增此实例的场景实例id
     * @param sceneInstIds
     * @param instType
     * @param instId
     * @return
     */
    private String getAddInstSceneInstId(List<String> sceneInstIds, InstType instType, String instId) {
        if (CollectionUtils.isEmpty(sceneInstIds) || Objects.isNull(instType) || StringUtils.isBlank(instId)) {
            return "";
        }

        if (sceneInstIds.size() == 1) {
            return sceneInstIds.get(0);
        }
        else {
            IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
            for (String sceneInstId : sceneInstIds) {
                if (querySceneInstService.isAddByCurrentSceneInst(sceneInstId, instType, instId)) {
                    return sceneInstId;
                }
            }
        }

        return "";
    }
}
